package com.hn.zhijian.system.rsasdk;

import com.alibaba.fastjson.JSON;

import java.util.Date;
import java.util.Optional;

/**
 * 服务
 */
public class SDKService implements ISDKService {

    private Resolve resolve;

    private IRedisOption option;

    public SDKService() {
        resolve = new DataResolve();
    }

    public SDKService(String publicKey, String privateKey) {
        resolve = new DataResolve(publicKey, privateKey);
    }

    public SDKService(String privateKey) {
        resolve = new DataResolve(privateKey);
    }

    @Override
    public ISDKService setPublicKey(String key) {
        resolve.setPublicKey(key);
        return this;
    }

    @Override
    public ISDKService setPrivateKey(String key) {
        resolve.setPrivateKey(key);
        return this;
    }

    @Override
    public boolean verify(String tick, String sign) throws ResolverException {
        //验证签名
        return Optional.ofNullable(resolve.verifySignature(tick, sign))
                .map(aBoolean -> {
                    if (aBoolean) {
                        return Optional.ofNullable(getTicket(tick)).map(item ->
                                TickAnalyticalValidation(item)
                        ).orElseThrow(() -> new ResolverException(ResolveException.TICK_LOAD_EXCEPTION));
                    }
                    return false;
                }).orElseThrow(() -> new ResolverException(ResolveException.WRONG_SIGNATURE_EXCEPTION));
    }


    /**
     * 效验ticker
     *
     * @param item
     */
    private boolean TickAnalyticalValidation(Ticket item) {
        if (null != option) {

            Optional.ofNullable(option.getTicket(item.getUid())).map(ticket -> {
                throw new ResolverException(ResolveException.TICK_USED_EXCEPTION);
            });

            option.addTicket(item.getUid(), item);
        }

        Long createTimer = item.getTimer();

        Long expireTimer = item.getExpire();

        //当前服务器时间
        Date currentTime = new Date();

        //过期时间
        Date outTime = getTimeOutDate(createTimer, expireTimer);

        if (currentTime.getTime() > outTime.getTime()) {
            throw new ResolverException(ResolveException.TICK_INVALID_EXCEPTION);
        }

        return true;
    }

    @Override
    public void redisOption(IRedisOption option) {
        this.option = option;
    }

    @Override
    public Ticket getTicket(String ticket) {
        return JSON.parseObject(resolve.ticket(ticket), Ticket.class);
    }

    private Date getTimeOutDate(Long createTimer, Long expireTimer) {
        return new Date(createTimeDate(createTimer).getTime() + expireTimer);
    }

    private Date createTimeDate(Long createTimer) {
        return new Date(createTimer);
    }

    @Override
    public String decode(String value) {
        return RSAUtils.decryptByPub(value.getBytes(), resolve.publicKey()) ;
    }

    @Override
    public String encode(String value) {
        return RSAUtils.encryptByPri(value.getBytes(), resolve.privateKey());
    }
}
